package com.okoj.excel_lib_rary.oss;

import android.content.Context;
import android.os.Build;
import android.text.TextUtils;

import com.alibaba.sdk.android.oss.ClientConfiguration;
import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
import com.alibaba.sdk.android.oss.common.OSSLog;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSCustomSignerCredentialProvider;
import com.alibaba.sdk.android.oss.common.utils.OSSUtils;
import com.alibaba.sdk.android.oss.model.DeleteObjectRequest;
import com.alibaba.sdk.android.oss.model.DeleteObjectResult;
import com.alibaba.sdk.android.oss.model.GetObjectRequest;
import com.alibaba.sdk.android.oss.model.GetObjectResult;
import com.alibaba.sdk.android.oss.model.OSSRequest;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.okoj.excel_lib_rary.util.FileUtil;
import com.okoj.excel_lib_rary.util.Md5Util;
import com.shineyie.android.oss.BuildConfig;
import com.shineyie.android.oss.OssResManager;

import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class OssManager {

    /**OSS服务器域名*/
    private static final String END_POINT_SHANGHAI = "oss-cn-shanghai.aliyuncs.com";
    private static final String END_POINT_SHENZHEN = "oss-cn-shenzhen.aliyuncs.com";

    /**访问KEY及密钥*/
    private static final String ACCESS_KEY = "LTAI4FukBBEZrdfviVTBPtzo";
    private static final String ACCESS_SECRET = "Q1qBK6xMqhlLzHclQcH4CY4jq61le4";

    /**bucket*/
    private static final String BUCKET_IJJ_STATIC = "ijj-static";
    /**bucket名为ijj-static对应的自定义域名*/
    private static final String IJJ_STATIC_END_POINT = "ijj-static.ijianji.cn";

    private static final String ROOT_FOLDER = "Vea/";
    private static final String AVATAR_FOLDER = ROOT_FOLDER + "avatar/";
    private static final String LOG_FOLDER = ROOT_FOLDER + "log/";
    private static final String CERTIFICATE_FOLDER = ROOT_FOLDER + "certificate/";
    private static final String FEED_BACK = ROOT_FOLDER + "feedback/";

    private static final long LIMIT_TIME = System.currentTimeMillis() + 60 * 60 * 24 * 365 * 100 * 1000;

    private static OssManager instance;
    private OSSClient ossClientToShanghai;
    private OSSClient ossClientToShenzhen;

    private OssManager() {
    }

    public synchronized static OssManager getInstance() {
        if (instance == null) {
            instance = new OssManager();
        }
        return instance;
    }

    public void init(Context context) {
        OssResManager.init(context, BuildConfig.DEBUG);
        OssConfig ossConfig = new OssConfig(END_POINT_SHANGHAI, ACCESS_KEY, ACCESS_SECRET);
//        ossClientToShanghai = createOssClient(context, ossConfig);
        ossClientToShanghai = OssResManager.getInstance().createStsOssClient(END_POINT_SHANGHAI);

        ossConfig = new OssConfig(END_POINT_SHENZHEN, ACCESS_KEY, ACCESS_SECRET);
        //ossClientToShenzhen = createOssClient(context, ossConfig);
        ossClientToShenzhen = OssResManager.getInstance().createStsOssClient(END_POINT_SHENZHEN);
    }

    private OSSClient createOssClient(Context context, final OssConfig ossConfig) {
        String endPoint = ossConfig.getEndPoint();
        OSSCredentialProvider provider = new OSSCustomSignerCredentialProvider() {
            @Override
            public String signContent(String content) {
                String signedString = OSSUtils.sign(ossConfig.getAccessKey(), ossConfig.getAccessSecret(), content);
                return signedString;
            }
        };
        ClientConfiguration clientConf = createClientConf();
        OSSClient ossClient = new OSSClient(context, endPoint, provider, clientConf);
        return ossClient;
    }

    private ClientConfiguration createClientConf() {
        ClientConfiguration conf = new ClientConfiguration();
        conf.setConnectionTimeout(15 * 1000); // 连接超时，默认15秒
        conf.setSocketTimeout(15 * 1000); // socket超时，默认15秒
        conf.setMaxConcurrentRequest(5); // 最大并发请求书，默认5个
        conf.setMaxErrorRetry(2); // 失败后最大重试次数，默认2次
        return conf;
    }

    /**
     * 将恢复会员认证图片上传到阿里云服务器上
     * @param imgPath
     * @param imgPathMd5 这个为参数imgPath对应的MD5值
     * @param listener
     */
    public void uploadCertificateToIjjStatic(String imgPath, String imgPathMd5, OssUploadListener listener) {
            String objectKey = null;
            final String CERTIFICATE = CERTIFICATE_FOLDER;
            if (TextUtils.isEmpty(imgPathMd5)) {
                objectKey = CERTIFICATE + UUID.randomUUID().toString() + ".jpg";
            } else {
                objectKey = CERTIFICATE + imgPathMd5 + ".jpg";
            }
        uploadFileToIjjStatic(objectKey, imgPath, listener);
    }

    /**
     * 将用户头像上传到OSS上
     * @param imgPath
     * @param fileName
     * @param listener
     */
    public void uploadAvatarToIjjStatic(String imgPath, String fileName, OssUploadListener listener) {
        String objectKey = null;
        final String AVATAR = AVATAR_FOLDER;
        if (TextUtils.isEmpty(fileName)) {
            objectKey = AVATAR + UUID.randomUUID().toString() + ".jpg";
        } else {
            objectKey = AVATAR + fileName + ".jpg";
        }
        uploadFileToIjjStatic(objectKey, imgPath, listener);
    }

    public void updateWpsFileToIjjStatic(String filePath,String fileName,String appid,String env,String userId,OssUploadListener listener ){

        String objectKey = null;
//        wps/ANDROID_com.qnjn.onnvjoq/1//b5cacf7a-5f50-494e-935d-197913fe0ef6..xlsx
        final String CERTIFICATE = String.format("wps/%s/%s/%s/",appid,env,userId);
            objectKey = CERTIFICATE + fileName;
        uploadFileToIjjStatic(objectKey, filePath, listener);
    }

    /**
     * 上传意见反馈图片
     * @param filePathList
     * @param listener
     */
    public void uploadFeedBackToIjjStatic(final List<String> filePathList, final OssUploadListener listener) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<String> objKeyList = new ArrayList<>();
                String locaFilePathMd5 = null;
                String objectKey = null;
                boolean ret = false;
                for (String path : filePathList) {
                    locaFilePathMd5 = Md5Util.getMd5OfString(path);
                    if (TextUtils.isEmpty(locaFilePathMd5)) {
                        objectKey = FEED_BACK + UUID.randomUUID().toString() + ".jpg";
                    } else {
                        objectKey = FEED_BACK + locaFilePathMd5 + ".jpg";
                    }
                    ret = uploadFileSync(BUCKET_IJJ_STATIC, objectKey, path);
                    if (ret) {
                        objKeyList.add(objectKey);
                    }
                }
                if (listener != null) {
                    if (objKeyList.size() == 0) {
                        listener.failure();
                    } else {
                        listener.success(objKeyList);
                    }
                }
            }
        }).start();
    }

    /**
     * 删除objectKey对应的头像
     * @param objectKey
     * @param callback
     */
    public void delAvatar(String objectKey, OSSCompletedCallback<DeleteObjectRequest, DeleteObjectResult> callback) {
        delFile(BUCKET_IJJ_STATIC, objectKey, callback);
    }

    public void uploadCrashLogToIjjStatic(String logPath, String md5, OssUploadListener listener) {
        String objectKey = generateLogKey(md5);
        uploadFileToIjjStatic(objectKey, logPath, listener);
    }

    public void uploadFileToIjjStatic(String objectKey, String filePath, final OssUploadListener listener) {
        uploadFile(BUCKET_IJJ_STATIC, objectKey, filePath, listener);
    }

    public void uploadFile(String bucket, String objectKey, String filePath, final OssUploadListener listener) {
        PutObjectRequest request = new PutObjectRequest(bucket, objectKey, filePath);
        request.setCRC64(OSSRequest.CRC64Config.YES);
        request.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
            @Override
            public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                int progress = (int) (100 * currentSize / totalSize);
                if (listener != null) {
                    listener.progress(progress);
                }
            }
        });

        ossClientToShanghai.asyncPutObject(request, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>(){
            @Override
            public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                if (listener != null) {
                    listener.success(request, result);
                }
            }

            @Override
            public void onFailure(PutObjectRequest request, ClientException clientException, ServiceException serviceException) {
                if (clientException != null) {
                    // 本地异常如网络异常等
                }
                if (serviceException != null) {
                    // 服务异常
                }
                if (listener != null) {
                    listener.failure();
                }
            }
        });
    }

    /**
     * 同步上传文件
     * @param bucket
     * @param objectKey
     * @param filePath
     * @return
     */
    public boolean uploadFileSync(String bucket, String objectKey, String filePath) {
        PutObjectRequest request = new PutObjectRequest(bucket, objectKey, filePath);
        request.setCRC64(OSSRequest.CRC64Config.YES);
        try {
            PutObjectResult result = ossClientToShanghai.putObject(request);
            int statusCode = result.getStatusCode();
            if (statusCode == 200) {
                return true;
            }
        } catch (ClientException e) {
            e.printStackTrace();
        } catch (ServiceException e) {
            e.printStackTrace();
        }
        return false;
    }

    public void delFile(String bucket, String objectKey, OSSCompletedCallback<DeleteObjectRequest, DeleteObjectResult> callback) {
        DeleteObjectRequest request = new DeleteObjectRequest(bucket, objectKey);
        ossClientToShanghai.asyncDeleteObject(request, callback);
    }

    public String getIjjStaticPrivateUrl(String objectKey) {
        String url = getPrivateUrl(BUCKET_IJJ_STATIC, objectKey);
        if (!TextUtils.isEmpty(url)) {
            String oldStr = BUCKET_IJJ_STATIC + "." + END_POINT_SHANGHAI;
            url = url.replace(oldStr, IJJ_STATIC_END_POINT);
        }
        return url;
    }

    public String getAuthUrl(String objectKey) {
        String url = getIjjStaticPrivateUrl(objectKey);
        try {
            url = url.split("\\?")[0];
        } catch (Exception e) {
            e.printStackTrace();
        }
        StringBuilder sbAuthKeyValue = new StringBuilder();
        StringBuilder sbSign = new StringBuilder();
        String fileName = objectKey;
        if (!fileName.startsWith("/")) {
            fileName = "/" + fileName;
        }
        final String timeStamp = ""+LIMIT_TIME;
        final String rand = UUID.randomUUID().toString().replace("-", "");
        final String uid = "0";
        final String sperator = "-";

        sbSign.append(fileName);
        sbSign.append(sperator);
        sbSign.append(timeStamp);
        sbSign.append(sperator);
        sbSign.append(rand);
        sbSign.append(sperator);
        sbSign.append(uid);
        sbSign.append(sperator);
        sbSign.append(AppConst.CDN_KEY);
        final String hashValue = Md5Util.getMd5OfString(sbSign.toString());

        sbAuthKeyValue.append(timeStamp);
        sbAuthKeyValue.append(sperator);
        sbAuthKeyValue.append(rand);
        sbAuthKeyValue.append(sperator);
        sbAuthKeyValue.append(uid);
        sbAuthKeyValue.append(sperator);
        sbAuthKeyValue.append(hashValue);

        url += "?auth_key=" + sbAuthKeyValue.toString();
        return url;
    }

    public String getPrivateUrl(String bucket, String objectKey) {
        if (TextUtils.isEmpty(objectKey)) {
            return "";
        }
        try {
            return ossClientToShanghai.presignConstrainedObjectURL(bucket, objectKey, LIMIT_TIME);
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return "";
    }

    private String generateLogKey(String md5) {
        StringBuilder sb = new StringBuilder();
        //log目录
        sb.append(LOG_FOLDER);
        //设备厂家目录
        String factory = Build.MANUFACTURER;
        if (TextUtils.isEmpty(factory)) {
            factory = "factory";
        }
        sb.append(factory+"/");
        //品牌目录
        String brand = Build.BRAND;
        if (TextUtils.isEmpty(brand)) {
            brand = "brand";
        }
        sb.append(brand + "/");
        //型号目录
        String model = Build.MODEL;
        if (TextUtils.isEmpty(model)) {
            model = Build.PRODUCT;
            if (TextUtils.isEmpty(model)) {
                model = "model";
            }
        }
        sb.append(model + "/");
        //文件名
        if (TextUtils.isEmpty(md5)) {
            //用时间来代替
            md5 = System.currentTimeMillis()+"";
        }
        sb.append(md5 + ".log");

        return sb.toString();
    }

    public OSSClient getOssClientToShanghai() {
        return ossClientToShanghai;
    }

    public OSSClient getOssClientToShenzhen() {
        return ossClientToShenzhen;
    }

    public void download(String bucketName,String objectKey,String downloadFilePath,OssDownloadListener ossDownloadListener){
        GetObjectRequest get = new GetObjectRequest(bucketName, objectKey);
        ossClientToShanghai.asyncGetObject(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() {
            @Override
            public void onSuccess(GetObjectRequest request, GetObjectResult result) {
                //开始读取数据。
                long length = result.getContentLength();
                byte[] buffer = new byte[(int) length];
                int readCount = 0;
                while (readCount < length) {
                    try{
                        readCount += result.getObjectContent().read(buffer, readCount, (int) length - readCount);
                    }catch (Exception e){
                        OSSLog.logInfo(e.toString());
                    }
                }
                 //将下载后的文件存放在指定的本地路径。
                try {
                    FileOutputStream fout = new FileOutputStream(downloadFilePath);
                    fout.write(buffer);
                    fout.close();
                    ossDownloadListener.success(downloadFilePath);
                } catch (Exception e) {
                    OSSLog.logInfo(e.toString());
                    ossDownloadListener.failure(e.getMessage());
                }
            }

            @Override
            public void onFailure(GetObjectRequest request, ClientException clientException, ServiceException serviceException) {
                ossDownloadListener.failure(clientException.getMessage()+"--"+serviceException.getMessage());
            }
        });
    }

    public void downloadWps(String downloadFilePath,String objectKey,OssDownloadListener ossDownloadListener){
        download(BUCKET_IJJ_STATIC,objectKey,downloadFilePath,ossDownloadListener);
    }

    public void delWpsFile(String objectkey,OSSCompletedCallback<DeleteObjectRequest, DeleteObjectResult> callback){
        delFile(BUCKET_IJJ_STATIC,objectkey,callback);
    }
}
